package com.ruoyi.aero.service.impl;

import java.util.Date;
import java.util.List;

import com.ruoyi.aero.domain.*;
import com.ruoyi.aero.enums.Scale;
import com.ruoyi.aero.enums.TaskStatus;
import com.ruoyi.aero.service.*;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.aero.mapper.TaskInfoMapper;
import org.springframework.util.ObjectUtils;

/**
 * 任务信息Service业务层处理
 * 
 * @author swb
 * @date 2024-06-05
 */
@Service
public class TaskInfoServiceImpl implements ITaskInfoService 
{
    @Autowired
    private TaskInfoMapper taskInfoMapper;

    @Autowired
    private IGroupInfoService groupInfoService;

    @Autowired
    private IStaffInfoService staffInfoService;

    @Autowired
    private IPlanInfoService planInfoService;

    /**
     * 查询任务信息
     * 
     * @param taskId 任务信息主键
     * @return 任务信息
     */
    @Override
    public TaskInfo selectTaskInfoByTaskId(String taskId)
    {
        TaskInfo taskInfo = taskInfoMapper.selectTaskInfoByTaskId(taskId);
        markStaff(taskInfo);
        updateStatus(taskInfo);
        return taskInfo;
    }

    /**
     * 查询任务信息列表
     * 
     * @param taskInfo 任务信息
     * @return 任务信息
     */
    @Override
    public List<TaskInfo> selectTaskInfoList(TaskInfo taskInfo)
    {
        List<TaskInfo> taskInfoList = taskInfoMapper.selectTaskInfoList(taskInfo);
        for (TaskInfo task : taskInfoList) {
            markStaff(task);
            updateStatus(task);
        }
        return taskInfoList;
    }

    /**
     * 新增任务信息
     * 
     * @param taskInfo 任务信息
     * @return 结果
     */
    @Override
    public int insertTaskInfo(TaskInfo taskInfo)
    {
        validDateTime(taskInfo);
        bindWorkshopOrGroup(taskInfo);
        taskInfo.setTaskId(IdUtils.randomUUID());
        taskInfo.setCreateTime(DateUtils.getNowDate());
        taskInfo.setCreateBy(SecurityUtils.getUsername());
        return taskInfoMapper.insertTaskInfo(taskInfo);
    }

    /**
     * 修改任务信息
     * 
     * @param taskInfo 任务信息
     * @return 结果
     */
    @Override
    public int updateTaskInfo(TaskInfo taskInfo)
    {
        validDateTime(taskInfo);
        bindWorkshopOrGroup(taskInfo);
        taskInfo.setUpdateTime(DateUtils.getNowDate());
        taskInfo.setUpdateBy(SecurityUtils.getUsername());
        return taskInfoMapper.updateTaskInfo(taskInfo);
    }

    /**
     * 批量删除任务信息
     * 
     * @param taskIds 需要删除的任务信息主键
     * @return 结果
     */
    @Override
    public int deleteTaskInfoByTaskIds(String[] taskIds)
    {
        return taskInfoMapper.deleteTaskInfoByTaskIds(taskIds);
    }

    /**
     * 删除任务信息信息
     * 
     * @param taskId 任务信息主键
     * @return 结果
     */
    @Override
    public int deleteTaskInfoByTaskId(String taskId)
    {
        return taskInfoMapper.deleteTaskInfoByTaskId(taskId);
    }

    /**
     * 标记车间和班组
     * @param taskInfo
     */
    private void mark(TaskInfo taskInfo) {
        String taskScale = taskInfo.getTaskScale();
        if (Scale.FACTORY_LEVEL.getScale().equals(taskScale)) {
            // 如果是厂级任务，则所属车间和班组置空
            taskInfo.setWorkshopId("无");
            taskInfo.setGroupId("无");
        } else if (Scale.WORKSHOP_LEVEL.getScale().equals(taskScale)) {
            // 如果是车间级任务，则班组置空
            taskInfo.setGroupId("无");
        } else if (Scale.GROUP_LEVEL.getScale().equals(taskScale)) {
            // 如果是班组级任务，则双属性均设置
            String groupId = taskInfo.getGroupId();
            GroupInfo groupInfo = groupInfoService.selectGroupInfoByGroupId(groupId);
            taskInfo.setWorkshopId(groupInfo.getWorkshopId());
        } else {
            throw new ServiceException("任务规模不合法");
        }
    }

    /**
     * 标记负责人信息
     * @param taskInfo
     */
    private void markStaff(TaskInfo taskInfo) {
        String taskScale = taskInfo.getTaskScale();
        if (Scale.WORKSHOP_LEVEL.getScale().equals(taskScale)) {
            // 如果是车间级别的任务
            WorkshopInfo workshopInfo = taskInfo.getWorkshopInfo();
            String workshopLeaderId = workshopInfo.getWorkshopLeaderId();
            if (ObjectUtils.isEmpty(workshopLeaderId)) return;
            StaffInfo staffInfo = staffInfoService.selectStaffInfoByStaffId(workshopLeaderId);
            taskInfo.setStaffInfo(staffInfo);
        } else if (Scale.GROUP_LEVEL.getScale().equals(taskScale)) {
            // 如果是班组级别的任务
            GroupInfo groupInfo = taskInfo.getGroupInfo();
            String groupLeaderId = groupInfo.getGroupLeaderId();
            if (ObjectUtils.isEmpty(groupLeaderId)) return;
            StaffInfo staffInfo = staffInfoService.selectStaffInfoByStaffId(groupLeaderId);
            taskInfo.setStaffInfo(staffInfo);
        }
    }

    /**
     * 判断起止日期是否合理
     * @param taskInfo
     */
    private void validDateTime(TaskInfo taskInfo) {
        String planId = taskInfo.getPlanId();
        if (ObjectUtils.isEmpty(planId)) {
            throw new ServiceException("所属计划不能为空");
        }

        Date taskStartTime = taskInfo.getStartTime();
        Date taskEndTime = taskInfo.getEndTime();
        if (taskStartTime.after(taskEndTime)) {
            throw new ServiceException("开始时间不能晚于结束时间");
        }

        PlanInfo planInfo = planInfoService.selectPlanInfoByPlanId(planId);
        Date planStartTime = planInfo.getStartTime();
        Date planEndTime = planInfo.getEndTime();
        if (taskStartTime.before(planStartTime) || taskEndTime.after(planEndTime)) {
            throw new ServiceException("任务起止时间必须在计划时间内");
        }
    }

    /**
     * 绑定车间或班组
     * @param taskInfo
     */
    private void bindWorkshopOrGroup(TaskInfo taskInfo) {
        String taskScale = taskInfo.getTaskScale();
        if (ObjectUtils.isEmpty(taskScale)) {
            throw new ServiceException("必须指定项目规模");
        }

        String planId = taskInfo.getPlanId();
        if (ObjectUtils.isEmpty(planId)) {
            throw new ServiceException("必须指定计划");
        }

        PlanInfo planInfo = planInfoService.selectPlanInfoByPlanId(planId);
        String planScale = planInfo.getPlanScale();
        if (Scale.WORKSHOP_LEVEL.getScale().equals(taskScale)) {
            // 若任务为车间级
            if (Scale.WORKSHOP_LEVEL.getScale().equals(planScale)) {
                // 若计划也为车间级
                taskInfo.setWorkshopId(planInfo.getWorkshopId()); // 项目所属车间和计划所属车间一致
            }
        } else if (Scale.GROUP_LEVEL.getScale().equals(taskScale)) {
            // 若任务为班组级
            if (Scale.WORKSHOP_LEVEL.getScale().equals(planScale)) {
                // 计划为车间级，则需比较选择的班组所在车间和计划是否一致
                String groupId = taskInfo.getGroupId();
                GroupInfo groupInfo = groupInfoService.selectGroupInfoByGroupId(groupId);
                if (ObjectUtils.isEmpty(groupInfo)) {
                    throw new ServiceException("班组无效");
                }
                String workshopId = groupInfo.getWorkshopId();
                if (!workshopId.equals(planInfo.getWorkshopId())) {
                    throw new ServiceException("选择的班组必须在计划对应的车间内");
                }

                // TODO 班组只能同时做一个任务

                taskInfo.setWorkshopId(workshopId);
            } else if (Scale.FACTORY_LEVEL.getScale().equals(planScale)) {
                // 计划为厂级
                String groupId = taskInfo.getGroupId();
                GroupInfo groupInfo = groupInfoService.selectGroupInfoByGroupId(groupId);
                if (ObjectUtils.isEmpty(groupInfo)) {
                    throw new ServiceException("班组无效");
                }
                String workshopId = groupInfo.getWorkshopId();
                taskInfo.setWorkshopId(workshopId);
            } else {
                throw new ServiceException("请先确定计划的规模");
            }
        } else {
            throw new ServiceException("任务规模只能为车间级或班组级");
        }
    }

    /**
     * 更新状态
     * @param taskInfo
     */
    private void updateStatus(TaskInfo taskInfo) {
        String taskStatus = taskInfo.getTaskStatus();
        if (TaskStatus.ON_GOING.getStatus().equals(taskStatus)) {
            // 如果任务正在进行中
            Date startTime = taskInfo.getStartTime();
            Date endTime = taskInfo.getEndTime();

            if (DateUtils.getNowDate().before(startTime)) {
                taskInfo.setTaskStatus(TaskStatus.NO_START.getStatus());
            } else if (DateUtils.getNowDate().after(endTime)) {
                taskInfo.setTaskStatus(TaskStatus.FINISHED.getStatus());
            }
            updateTaskInfo(taskInfo);
        }
    }
}
